home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
-
- Author: Dale Roberts
- Date: 8/30/95
- Program: TOTALIO.SYS
- Compile: Use DDK BUILD facility
-
- Purpose: Give direct port I/O access to the whole system.
-
- This driver grants total system-wide I/O access to all applications.
- Very dangerous, but useful for short tests. Note that no test
- application is required. Just use control panel or
- "net start totalio" to start the device driver. When the driver
- is stopped, total I/O is removed. Because no Win32 app needs to
- communicate with the driver, we don't have to create a device object.
- So we have a very tiny driver here.
-
- Since we can safely extend the TSS only to the end of the physical
- memory page in which it lies, the I/O access is granted only up to
- port 0xf00. Accesses beyond this port address will still generate
- exceptions.
-
- *********************************************************************/
- #include <ntddk.h>
-
- /*
- * Make sure our structure is packed properly, on byte boundary, not
- * on the default doubleword boundary.
- */
- #pragma pack(push,1)
-
- /*
- * Structures for manipulating the GDT register and a GDT segment
- * descriptor entry. Documented in Intel processor handbooks.
- */
- typedef struct {
- unsigned limit : 16;
- unsigned baselo : 16;
- unsigned basemid : 8;
- unsigned type : 4;
- unsigned system : 1;
- unsigned dpl : 2;
- unsigned present : 1;
- unsigned limithi : 4;
- unsigned available : 1;
- unsigned zero : 1;
- unsigned size : 1;
- unsigned granularity : 1;
- unsigned basehi : 8;
- } GDTENT;
-
- typedef struct {
- unsigned short limit;
- GDTENT *base;
- } GDTREG;
-
- #pragma pack(pop)
-
- /*
- * This is the lowest level for setting the TSS segment descriptor
- * limit field. We get the selector ID from the STR instruction,
- * index into the GDT, and poke in the new limit. In order for the
- * new limit to take effect, we must then read the task segment
- * selector back into the task register (TR).
- */
- void SetTSSLimit(int size)
- {
- GDTREG gdtreg;
- GDTENT *g;
- short TaskSeg;
-
- _asm cli; // don't get interrupted!
- _asm sgdt gdtreg; // get GDT address
- _asm str TaskSeg; // get TSS selector index
- g = gdtreg.base + (TaskSeg >> 3); // get ptr to TSS descriptor
- g->limit = size; // modify TSS segment limit
- //
- // MUST set selector type field to 9, to indicate the task is
- // NOT BUSY. Otherwise the LTR instruction causes a fault.
- //
- g->type = 9; // mark TSS as "not busy"
- //
- // We must do a load of the Task register, else the processor
- // never sees the new TSS selector limit.
- //
- _asm ltr TaskSeg; // reload task register (TR)
- _asm sti; // let interrupts continue
- }
-
- /*
- * This routine gives total I/O access across the whole system.
- * It does this by modifying the limit of the TSS segment by direct
- * modification of the TSS descriptor entry in the GDT.
- * This descriptor is set up just once at sysetem init time. Once we
- * modify it, it stays untouched across all processes.
- */
- void GiveTotalIO(void)
- {
- SetTSSLimit(0x20ab + 0xf00);
- }
-
- /*
- * This returns the TSS segment to its normal size of 0x20ab, which
- * is two less than the default I/O map base address of 0x20ad.
- */
- void RemoveTotalIO(void)
- {
- SetTSSLimit(0x20ab);
- }
-
- /****************************************************************************
- Release all memory 'n' stuff.
- ****************************************************************************/
- VOID
- TotalIOdrvUnload(
- IN PDRIVER_OBJECT DriverObject
- )
- {
- RemoveTotalIO();
- }
-
- /****************************************************************************
- Entry routine. Set everything up.
- ****************************************************************************/
- NTSTATUS DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
- {
- DriverObject->DriverUnload = TotalIOdrvUnload;
- GiveTotalIO();
- return STATUS_SUCCESS;
- }
-
-